#!/usr/bin/env python
# $Id: sftp.py df54dec975f4 2012/09/09 20:22:40 pgurumur $
# Copyright (c) 2009 Prabhu Gurumurthy  <pgurumur@gmail.com>
# 
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#

__version__ = "$Revision: df54dec975f4 $"
__author__ = "$Author: pgurumur $"

# system imports
import getpass
import os
import optparse
import signal
import sys

# local imports
# import cmdparser library to handle command line arguments
from venya.lib import cmdparser

# Import the core of the ssh implementation using paramiko
from venya.lib import sshlib
from venya.lib import log
from venya.lib import stdlib
from venya.lib import console

# Main client class, which imports the command parser class, the actual
# ssh handling is done using the handle function

# Main SSH client class
class sshclient(cmdparser.GetOpt):
   option_list = (
         optparse.make_option("-4", action = "store_true",
            help = "Use IPv4 for connecting", default = False, dest = "v4"),
         optparse.make_option("-6", action = "store_true",
            help = "Use IPv6 for connecting", default = False, dest = "v6"),
         optparse.make_option("-l", "--login", type = "str",
            help = "Username for SSH session", dest = "login"),
         optparse.make_option("-f", "--filename", type = "str",
            help = "Filename to parse and send to SSH server",
            dest = "filename"),
         optparse.make_option("-p", "--port", type = "int",
            help = "SSH port to use, default: 22", default = 22,
            dest = "port"),
         optparse.make_option("-P", "--password", type = "str",
            help = "Password to use for the username", dest = "password"),
         ) + cmdparser.GetOpt.option_list

   help = """
   SSH client using paramiko
   """

   def __init__(self, **keywords):
      super(self.__class__, self).__init__(**keywords)
      self._log = log.StreamLog(stdlib.my_name(self))
      self._client = None
      self._host = None

   def close(self):
      if self._client:
         self._client.Close()
         self._client = None

   def sighandle(self, signal, frame):
      print "\n"
      self.error("program with pid %d terminated with signal: %d",
            os.getpid(), signal)

   def setsignal(self, flag = True):
      func = None
      if flag:
         func = self.sighandle
      else:
         func = signal.SIG_IGN

      try:
         signal.signal(signal.SIGTERM, func)
         signal.signal(signal.SIGINT, func)
         signal.signal(signal.SIGHUP, func)
      except ValueError, message:
         pass

   def handle(self):
      (options, args) = self.parse()

      username = None
      password = None
      filename = None
      port = 22

      self.setsignal()

      try:
         self._host = args[1]
      except IndexError, message:
         self.error("Cannot proceed without any host name!")

      if options.login:
         username = options.login.strip()
      else:
         username = getpass.getuser()

      if options.port:
         try:
            port = int(options.port)
         except ValueError, message:
            self.error(message)

      if options.password:
         password = options.password.strip()

      if options.filename:
         filename = options.filename.strip()

      try:
         self._client = sshlib.SSHClient(host = self._host.strip(),
               user = username, port = port, verbose = bool(options.verbosity),
               passwd = password)
         if options.v4:
            self._client.Connect(family = 4)
         elif options.v6:
            self._client.Connect(family = 6)
         else:
            self._client.Connect()

         retval = self._client.Auth(bool(password))
         if not retval:
            self.error("cannot authenticate to %s", host)
         else:
            if not options.filename:
               self.setsignal(False)

            self._client.GetChannel(exfile = filename)
      except sshlib.SSHException, message:
         self.error(message)

if __name__ == "__main__":
   client = None
   try:
      client = sshclient(version = 1.2, args = sys.argv, usage = "host")
      if len(client) <= 1:
         client.printhelp()
      else:
         client.handle()
   except cmdparser.GetOptError, message:
      print message
      sys.exit(1)
   finally:
      if client:
         client.close()
